﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using BlobNet.Base;
using BlobNet.Base.DataProviders;
using BlobNet.Base.Enums;
using BlobNet.Base.Interfaces;
using BlobNet.Base.Storage;
using BlobNet.TestsCommon.UnitTests.Dummy;
using Rhino.Mocks;

namespace BlobNet.TestsCommon.Utils
{
    public static class TestsHelper
    {
        public static IStorageManagerFactory GetStubFactory(out IStorageManager memPersistor)
        {
            IStorageManager none;
            return GetStubFactory(out memPersistor, out none);
        }

        public static IStorageManagerFactory GetStubFactory(out IStorageManager memPersistor,
                                                            out IStorageManager dbPersistor)
        {
            dbPersistor = MockRepository.GenerateStub<IStorageManager>();
            memPersistor = MockRepository.GenerateStub<IStorageManager>();
            var factory = MockRepository.GenerateStub<IStorageManagerFactory>();
            factory.Stub(
                x =>
                x.CreateStorage(Arg<StatusStorageType>.Is.Equal(StatusStorageType.Persistent),
                                Arg<Guid>.Is.Anything, Arg<BlobDomain>.Is.Anything)).Return(dbPersistor);
            factory.Stub(
                x =>
                x.CreateStorage(Arg<StatusStorageType>.Is.Equal(StatusStorageType.Memory),
                                Arg<Guid>.Is.Anything, Arg<BlobDomain>.Is.Anything)).Return(memPersistor);

            memPersistor.Stub(x => x.GetVariantSourcesItems()).Return(new List<IPersisteable>());
            dbPersistor.Stub(x => x.GetVariantSourcesItems()).Return(new List<IPersisteable>());

            return factory;
        }

        public static BlobDomain GetDummyBlobDomain()
        {
            IStorageManager memPersistor;
            IStorageManager dbPersistor;
            IStorageManagerFactory shStorageFactory = GetStubFactory(out memPersistor, out dbPersistor);
            memPersistor.Stub(x => x.CanDettach()).Return(true);
            dbPersistor.Stub(x => x.CanDettach()).Return(true);
            DataProviderFactory.Provider=GetStubDataProvider();
            BlobDomain result = new DummyBlobDomainHolder(Guid.NewGuid(), shStorageFactory);

            return result;
        }

        public static IDataProvider GetStubDataProvider()
        {
            var result = MockRepository.GenerateStub<IDataProvider>();
            result.Stub(x => x.CreateSchema(Arg<Guid>.Is.Anything));
            result.Stub(x => x.RemoveSchema(Arg<Guid>.Is.Anything));

            return result;
        }

        public static MemoryStream Serialize(object source)
        {
            var memoryStream = new MemoryStream();

            var binaryFormatter = new BinaryFormatter();

            binaryFormatter.Serialize(memoryStream, source);

            return memoryStream;
        }

        public static T Deserialize<T>(MemoryStream memoryStream)
        {
            var binaryFormatter = new BinaryFormatter();
            memoryStream.Seek(0, SeekOrigin.Begin);

            return (T) binaryFormatter.Deserialize(memoryStream);
        }
    }
}